home *** CD-ROM | disk | FTP | other *** search
- #include "xinternl.h"
- #include <conio.h>
- /*==================================================================
- XSCALEBM.CPP contains the basic functions for bitmap scaling in
- mode X.
-
- These routines were written initially by John P. Slagel and
- company and modified March 1995 by Victor B. Putz.
- ===================================================================*/
-
- extern xScreenCoord_t LeftClip;
- extern xScreenCoord_t RightClip;
- extern xScreenCoord_t TopClip;
- extern xScreenCoord_t BottomClip;
-
- extern int ScrnLogicalByteWidth;
-
- extern BYTE * pbVGABuffer;
-
- void x_scale_bm(
- xScreenCoord_t iDestX,
- xScreenCoord_t iDestY,
- int iDestWidth,
- int iDestHeight,
- xPageHandle_t ScrnOffs,
- BYTE * pbData
- )
- {
- //get width and height;
- int iSourceWidth = *pbData++;
- int iSourceHeight = *pbData++;
- //now check for "too small" puts ( width or height < 2 )
- if ( ( iDestWidth < 2 ) ||
- ( iDestHeight < 2 ) ) {
- return;
- }
- //now check for out-of-bounds puts, basing of pixel-sized clipping
- //boundaries ( rather than nibble-sized clipping boundaries )
- int iLeftPixelClip = LeftClip << 2;
- int iRightPixelClip = RightClip << 2;
- if ( ( iDestY > BottomClip ) ||
- ( ( iDestY + iDestHeight - 1 ) < TopClip ) ||
- ( iDestX > iRightPixelClip ) ||
- ( ( iDestY + iDestWidth - 1 ) < iLeftPixelClip ) ) {
- return;
- }
- //for now, clipped width = destination width, set up decision X variable
- int iClippedWidth = iDestWidth;
- int iDecisionX = -iDestWidth;
- //clipped height and decision Y variable
- int iClippedHeight = iDestHeight;
- int iDecisionY = -iDestHeight;
- //...and offset into source map
- int iSourceOffset = 0;
- //check for clipping in the Y axis, first checking top
- if ( iDestY < TopClip ) {
- int iClippedRows = TopClip - iDestY;
- iClippedHeight -= iClippedRows;
- iDestY = TopClip;
- for ( int i = iClippedRows; i > 0; --i ) {
- iDecisionY += iSourceHeight;
- if ( iDecisionY >= 0 ) {
- while ( iDecisionY >= 0 ) {
- iDecisionY -= iDestHeight;
- iSourceOffset += iSourceWidth;
- }
- }
- }
- }
- //then checking bottom...
- int iBottomRow = iDestY + iClippedHeight - 1;
- if ( iBottomRow > BottomClip ) {
- iClippedHeight -= ( iBottomRow - BottomClip );
- }
- //then check for left clipping...
- if ( iDestX < iLeftPixelClip ) {
- int iClippedColumns = iLeftPixelClip - iDestX;
- iClippedWidth -= iClippedColumns;
- iDestX = iLeftPixelClip;
- for ( int i = iClippedColumns; i > 0; --i ) {
- iDecisionX += iSourceWidth;
- if ( iDecisionX >= 0 ) {
- while ( iDecisionX >= 0 ) {
- iDecisionX -= iDestWidth;
- iSourceOffset++;
- }
- }
- }
- }
- int iRightRow = iDestX + iClippedWidth - 1;
- if ( iRightRow > iRightPixelClip ) {
- iClippedWidth -= ( iRightRow - iRightPixelClip );
- }
-
- //Okay! The clipping is done, so let's find our source and
- //destination pointers.
- BYTE * pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * iDestY ) + iDestX / 4;
- BYTE * pbSource = pbData + iSourceOffset;
- int iWidthCounter = iClippedWidth;
- //set up the controller to switch planes
- outp( SC_INDEX, MAP_MASK );
- int iPlane = iDestX & 0x03;
- outp( SC_INDEX + 1, 1 << iPlane );
- //now set up some "old position" pointers so we can rewind reliably
- BYTE * pbDestStart = pbDest;
- BYTE * pbSourceStart = pbSource;
-
- while ( iWidthCounter-- ) {
- int iHeightCounter = iClippedHeight;
- int iDecisionYCount = iDecisionY;
- BYTE b = *pbSource;
- while ( iHeightCounter-- ) {
- //plot the pixel and go to the next pixel down.
- *pbDest = b;
- pbDest += ScrnLogicalByteWidth;
- //now increment our decision Y variable and get the next source
- //pixel if need be
- iDecisionYCount += iSourceHeight;
- if ( iDecisionYCount >= 0 ) {
- while ( iDecisionYCount >= 0 ) {
- iDecisionYCount -= iDestHeight;
- pbSource += iSourceWidth;
- }
- b = *pbSource;
- }
- }
- //now go to the next screen column
- ++iPlane;
- //if we've wrapped over our 4-plane boundary, increase the VGA start
- //by one pixel.
- if ( iPlane & 0x04 ) {
- pbDestStart++;
- iPlane &= 0x03;
- }
- outp( SC_INDEX + 1, 1 << iPlane );
- pbDest = pbDestStart;
- //now increment our decision X variable and go to the next source column
- //if need be;
- iDecisionX += iSourceWidth;
- if ( iDecisionX >= 0 ) {
- while ( iDecisionX >= 0 ) {
- iDecisionX -= iDestWidth;
- pbSourceStart++;
- }
- }
- pbSource = pbSourceStart;
- }
- }
-
- /*
- The scaling version of the routine is the exact same code, with the addition
- of a check to make sure the color is not zero before blitting.
- */
- void x_scale_masked_bm(
- xScreenCoord_t iDestX,
- xScreenCoord_t iDestY,
- int iDestWidth,
- int iDestHeight,
- xPageHandle_t ScrnOffs,
- BYTE * pbData
- )
- {
- //get width and height;
- int iSourceWidth = *pbData++;
- int iSourceHeight = *pbData++;
- //now check for "too small" puts ( width or height < 2 )
- if ( ( iDestWidth < 2 ) ||
- ( iDestHeight < 2 ) ) {
- return;
- }
- //now check for out-of-bounds puts, basing of pixel-sized clipping
- //boundaries ( rather than nibble-sized clipping boundaries )
- int iLeftPixelClip = LeftClip << 2;
- int iRightPixelClip = RightClip << 2;
- if ( ( iDestY > BottomClip ) ||
- ( ( iDestY + iDestHeight - 1 ) < TopClip ) ||
- ( iDestX > iRightPixelClip ) ||
- ( ( iDestX + iDestWidth - 1 ) < iLeftPixelClip ) ) {
- return;
- }
- //for now, clipped width = destination width, set up decision X variable
- int iClippedWidth = iDestWidth;
- int iDecisionX = -iDestWidth;
- //clipped height and decision Y variable
- int iClippedHeight = iDestHeight;
- int iDecisionY = -iDestHeight;
- //...and offset into source map
- int iSourceOffset = 0;
- //check for clipping in the Y axis, first checking top
- if ( iDestY < TopClip ) {
- int iClippedRows = TopClip - iDestY;
- iClippedHeight -= iClippedRows;
- iSourceOffset += iClippedRows * iSourceWidth;
- iDestY = TopClip;
- iDecisionY += iClippedRows * iSourceHeight;
- while ( iDecisionY > 0 ) {
- iDecisionY -= iDestHeight;
- }
- }
- //then checking bottom...
- int iBottomRow = iDestY + iClippedHeight - 1;
- if ( iBottomRow > BottomClip ) {
- iClippedHeight -= ( iBottomRow - BottomClip );
- }
- //then check for left clipping...
- if ( iDestX < iLeftPixelClip ) {
- int iClippedColumns = iLeftPixelClip - iDestX;
- iClippedWidth -= iClippedColumns;
- iSourceOffset += iClippedColumns;
- iDestX = iLeftPixelClip;
- iDecisionX += iClippedColumns * iSourceWidth;
- while ( iDecisionX > 0 ) {
- iDecisionX -= iDestWidth;
- }
- }
- int iRightRow = iDestX + iClippedWidth - 1;
- if ( iRightRow > iRightPixelClip ) {
- iClippedWidth -= ( iRightRow - iRightPixelClip );
- }
-
- //Okay! The clipping is done, so let's find our source and
- //destination pointers.
- BYTE * pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * iDestY ) + iDestX / 4;
- BYTE * pbSource = pbData + iSourceOffset;
- int iWidthCounter = iClippedWidth;
- //set up the controller to switch planes
- outp( SC_INDEX, MAP_MASK );
- int iPlane = iDestX & 0x03;
- outp( SC_INDEX + 1, 1 << iPlane );
- //now set up some "old position" pointers so we can rewind reliably
- BYTE * pbDestStart = pbDest;
- BYTE * pbSourceStart = pbSource;
-
- while ( iWidthCounter-- ) {
- int iHeightCounter = iClippedHeight;
- int iDecisionYCount = iDecisionY;
- BYTE b = *pbSource;
- while ( iHeightCounter-- ) {
- //plot the pixel and go to the next pixel down.
- if ( b != 0 ) {
- *pbDest = b;
- }
- pbDest += ScrnLogicalByteWidth;
- //now increment our decision Y variable and get the next source
- //pixel if need be
- iDecisionYCount += iSourceHeight;
- if ( iDecisionYCount >= 0 ) {
- while ( iDecisionYCount >= 0 ) {
- iDecisionYCount -= iDestHeight;
- pbSource += iSourceWidth;
- }
- b = *pbSource;
- }
- }
- //now go to the next screen column
- ++iPlane;
- //if we've wrapped over our 4-plane boundary, increase the VGA start
- //by one pixel.
- if ( iPlane & 0x04 ) {
- pbDestStart++;
- iPlane &= 0x03;
- }
- outp( SC_INDEX + 1, 1 << iPlane );
- pbDest = pbDestStart;
- //now increment our decision X variable and go to the next source column
- //if need be;
- iDecisionX += iSourceWidth;
- if ( iDecisionX >= 0 ) {
- while ( iDecisionX >= 0 ) {
- iDecisionX -= iDestWidth;
- pbSourceStart++;
- }
- }
- pbSource = pbSourceStart;
- }
- }
-